package com.illumination.monitor.common.utils;


import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Date;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.digest.DigestUtils;

import lombok.SneakyThrows;

/**
 * AES 加密方法，是对称的密码算法(加密与解密的密钥一致)，这里使用最大的 256 位的密钥
 */
public class AESUtil {
	/**
	 * 获得一个随机密钥长度为 128 位的 AES 密钥，
	 * @return 返回经 BASE64 处理之后的密钥字符串
	 */
	public static String getStrKeyAES(String rule) throws NoSuchAlgorithmException, UnsupportedEncodingException {
		KeyGenerator keyGen = KeyGenerator.getInstance("AES");
		SecureRandom secureRandom = new SecureRandom(rule.getBytes("utf-8"));
		keyGen.init(128, secureRandom);
		SecretKey secretKey = keyGen.generateKey();
		return Base64.getEncoder().encodeToString(secretKey.getEncoded());
	}

	/**
	 *  将使用 Base64 加密后的字符串类型的 secretKey 转为 SecretKey
	 * @param strKey
	 * @return SecretKey
	 */
	public static SecretKey strKey2SecretKey(String strKey){
		//byte[] bytes = Base64.getDecoder().decode(strKey);
		SecretKeySpec secretKey = new SecretKeySpec(strKey.getBytes(), "AES");
		return secretKey;
	}

	/**
	 * 加密
	 * @param content 待加密内容
	 * @param secretKey 加密使用的 AES 密钥
	 * @return 加密后的密文 byte[]
	 */
	public static byte[] encryptAES(byte[] content, SecretKey secretKey) throws Exception {
		Cipher cipher = Cipher.getInstance("AES");
		cipher.init(Cipher.ENCRYPT_MODE, secretKey);
		return cipher.doFinal(content);
	}

	/**
	 * 解密
	 * @param content 待解密内容
	 * @param secretKey 解密使用的 AES 密钥
	 * @return 解密后的明文 byte[]
	 */
	public static byte[] decryptAES(byte[] content, SecretKey secretKey) throws Exception {
		Cipher cipher = Cipher.getInstance("AES");
		cipher.init(Cipher.DECRYPT_MODE, secretKey);
		return cipher.doFinal(content);
	}
	
	public static @SneakyThrows  SecretKey MD5TimeKeyPrefix(String annex) {
		String md5Hex = DigestUtils.md5Hex(DateUtils.format(new Date(), "yyyyddMM").concat(annex));
		return AESUtil.strKey2SecretKey(md5Hex.substring(8, 24));
	}
	
//	public @SneakyThrows static void main(String[] args) {
//		byte[] aes = AESUtil.decryptAES(Base64.getDecoder().decode("sTpIwFI8tIVSVquTh82iUg=="), AESUtil.MD5TimeKeyPrefix("18832535678"));
//		System.err.println(new String(aes));
//	}

}